package cn.stronglink.asset.terminal.bjc.log.aspect;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.aopalliance.intercept.Joinpoint;
import org.apache.poi.ss.formula.functions.T;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.toolkit.IdWorker;

import cn.stronglink.asset.model.Preset;
import cn.stronglink.asset.model.PullOff;
import cn.stronglink.asset.model.PutOn;
import cn.stronglink.asset.model.SysOperateLog;
import cn.stronglink.asset.model.User;
import cn.stronglink.asset.module.sys.log.service.SysLogService;
import cn.stronglink.asset.module.sys.user.service.UserService;
import cn.stronglink.asset.terminal.bjc.log.annotation.PdaLog;
import cn.stronglink.asset.terminal.bjc.log.annotation.PdaLog.OpType;
import cn.stronglink.asset.terminal.bjc.model.PatrolVo;
import cn.stronglink.asset.terminal.bjc.model.UploadInventoryParam;
import cn.stronglink.suite.core.util.WebUtil;

/**
 * @author sunlei:
 * @version 创建时间：2018年3月6日 下午3:04:59 类说明
 */
@Aspect
@Component
public class PdaLogImpl {
	@Autowired
	private SysLogService sysLogService;
	@Autowired
	private UserService userService;
	//private static final Logger logger = LoggerFactory.getLogger(PdaLogImpl.class);

	 @Before(value = "@annotation(cn.stronglink.asset.terminal.bjc.log.annotation.PdaLog)")
	 public void doBefor(JoinPoint joinPoint) throws Exception {
		 System.out.println("-----doBefor-----");
		 handleLog(joinPoint,null);
	 }
	//
	// @AfterReturning("@annotation(cn.stronglink.asset.terminal.bjc.log.annotation.PdaLog)")
	// public void doAfter() {
	// System.out.println("-----doAfter-----");
	// }

	//@Around(value = "@annotation(cn.stronglink.asset.terminal.bjc.log.annotation.PdaLog) && @annotation(annotation)")
	public void handleLog(JoinPoint joinPoint, PdaLog annotation ) throws Exception{
		System.out.println("-----doing----handleLog-");

		// 获得注解
		PdaLog logger = giveController(joinPoint);
		if (logger == null) {
			return;
		}
		String signature = joinPoint.getSignature().toString(); // ��ȡĿ�귽��ǩ��
		String methodName = signature.substring(signature.lastIndexOf(".") + 1, signature.indexOf("("));

		String longTemp = joinPoint.getStaticPart().toLongString();
		String classType = joinPoint.getTarget().getClass().getName();
		Class<?> clazz = Class.forName(classType);
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {

			if (method.isAnnotationPresent(PdaLog.class) && method.getName().equals(methodName)) {
				Long userId = getUserIdByArgs(joinPoint.getArgs());
				if (userId == null) {
					return;
				}
				String username = "", actName = "";
				User user = userService.qryUserById(userId);
				actName = user.getName();
				username = user.getAccount();
				OpType type = logger.type();
				if ("SEARCH".equals(type.toString())) {
					return;
				}
				String module = logger.module();
				String desc = logger.desc();
				SysOperateLog log = new SysOperateLog();
				log.setId(IdWorker.getId());
				log.setArgs(optionContent(joinPoint.getArgs(), methodName));
				log.setActName(actName);
				log.setUserName(username);
				log.setModule(module);
				log.setOperateTime(new Date());
				log.setOperateType(type.toString());
				log.setDescription(desc);
				sysLogService.insertOperateLog(log);

			}
		}
	}
	private static PdaLog giveController(JoinPoint joinPoint) throws Exception {
		Signature signature = joinPoint.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();

		if (method != null) {
			return method.getAnnotation(PdaLog.class);
		}
		return null;
	}
	/**
	 * 使用Java反射来获取被拦截方法(insert、update)的参数值， 将参数值拼接为操作内容
	 */
	public String optionContent(Object[] args, String mName) throws Exception {
		// System.out.println(JSON.toJSON(args));
		if (args == null) {
			return null;
		}
		StringBuffer rs = new StringBuffer();
		rs.append(mName);
		String className = null;
		int index = 1;
		for (Object info : args) {
			// ��ȡ��������
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			if ("ShiroHttpServletRequest".equals(className) || "ShiroHttpServletResponse".equals(className)
					|| "BindingAwareModelMap".equals(className) || "RequestFacade".equals(className)
					|| "ResponseFacade".equals(className)
					|| "CookieHttpSessionStrategy$MultiSessionHttpServletResponse".equals(className)) {
				continue;
			}
			String arg = JSON.toJSONString(info);
			rs.append("[参数" + index + "，值：" + arg);

			rs.append("]");
			index++;
		}
		return rs.toString();
	}
	@SuppressWarnings("unchecked")
	public Long getUserIdByArgs(Object[] args){
		Long userId = null;
		if (args == null) {
			return null;
		}
		String className = null;
		for (Object info : args) {
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			if ("ShiroHttpServletRequest".equals(className) || "ShiroHttpServletResponse".equals(className)
					|| "BindingAwareModelMap".equals(className) || "RequestFacade".equals(className)
					|| "ResponseFacade".equals(className)
					|| "CookieHttpSessionStrategy$MultiSessionHttpServletResponse".equals(className)) {
				continue;
			}
			if("HashMap".equals(className)){//绑定 rfid
				HashMap<String, String> map = new HashMap<>();
				map = (HashMap<String, String>) info;
				userId = Long.parseLong(map.get("updateBy"));
			}else if("ArrayList".equals(className)){///////?????
				ArrayList<T> list = (ArrayList<T>) info;
				if(list.size()>0){
					for (int i = 0;i<list.size();i++) {
						Object o = list.get(i);
						if(o instanceof Preset){//验收
							Preset p = (Preset) o;
						    userId = p.getUpdateBy();
						}else if(o instanceof PutOn){//上架
							PutOn p = (PutOn) o;
						    userId = p.getUpdateBy();
						}else if(o instanceof PullOff){//下架
							PullOff p = (PullOff) o;
						    userId = p.getUpdateBy();
						}else if(o instanceof PatrolVo){//巡检
							PatrolVo p = (PatrolVo) o;
						    userId = p.getUpdateBy();
						}else if(o instanceof UploadInventoryParam){//盘点
							UploadInventoryParam p = (UploadInventoryParam) o;
						    userId = p.getUpdateBy();
						}
					}
				}
				
//				if(object.getClass())
//				info.getClass();
			}
			
		}
		return userId;
	}
}
